/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cratos.xxgramoss.user;

import com.cratos.xxgram.platf.base.BaseService;
import javax.annotation.Resource;
import org.redkale.net.http.RestService;
import org.redkale.source.*;
import org.redkale.util.*;
import static com.cratos.xxgramoss.base.Services.*;
import com.cratos.xxgram.platf.base.UserInfo;
import com.cratos.xxgram.platf.complaint.ComplaintRecord;
import com.cratos.xxgram.platf.facade.OssService;
import com.cratos.xxgram.platf.friend.FriendShip;
import com.cratos.xxgram.platf.group.GroupDetail;
import com.cratos.xxgram.platf.group.UserGroup;
import com.cratos.xxgram.platf.message.BasicContent;
import com.cratos.xxgram.platf.message.MessageRecordHis;
import com.cratos.xxgram.platf.user.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.redkale.net.http.*;
import org.redkale.service.RetResult;

/**
 *
 * @author alter
 */
@RestService(comment = "用户信息", moduleid = MODULE_USER)
public class UserOssService extends BaseService {

    @Resource(name = "platf")
    protected DataSource platfSource;

    @Resource(name = "wsim")
    protected WebSocketNode webSocketNode;
    
    @Resource
    protected OssService ossService;

    //@RestConvert(type = UserDetail.class,ignoreColumns = {"regtime","username"},convertColumns = {"regtime","username"})
    @RestMapping(auth = true, actionid = ACTION_QUERY, comment = "查询用户列表")
    public RetResult<Sheet<UserDetail>> queryUserList(UserDetailBean bean, Flipper flipper) {
        ArrayList<UserDetail> list = new ArrayList<>();
        CompletableFuture<Set<String>> userOnline = webSocketNode.getUserSet();
        System.out.println(userOnline.join() + "--" + userOnline.join().size());
        if (bean != null && bean.getOnlinestatus() == UserDetail.ONLINE_STATUS_ONLINE) {
            int[] userid = new int[userOnline.join().size()];
            int i = 0;
            for (String id : userOnline.join()) {
                userid[i] = Integer.parseInt(id);
                i++;
            }
            bean.setOnlinestatus((short) 0);
            bean.setUserid(userid);
            List<UserDetail> online = platfSource.queryList(UserDetail.class, flipper, bean);
            online.forEach(user -> user.setOnlinestatus(UserDetail.ONLINE_STATUS_ONLINE));
            return new RetResult<>(new Sheet<>(userOnline.join().size(), online));
        } else if (bean != null && bean.getOnlinestatus() == UserDetail.ONLINE_STATUS_OFFLINE) {
            bean.setOnlinestatus((short) 0);
            int count = platfSource.getNumberResult(UserDetail.class, FilterFunc.COUNT, 0, null, bean).intValue();
            List<UserDetail> off = platfSource.queryList(UserDetail.class, flipper, bean);
            for (UserDetail user : off) {
                for (String id : userOnline.join()) {
                    if (user.getUserid() != Integer.parseInt(id)) {
                        user.setOnlinestatus(UserDetail.ONLINE_STATUS_OFFLINE);
                    }
                }
                list.add(user);
            }
            return new RetResult<>(new Sheet<>(count - userOnline.join().size(), list));
        } else {
            int count = platfSource.getNumberResult(UserDetail.class, FilterFunc.COUNT, 0, null, bean).intValue();
            List<UserDetail> all = platfSource.queryList(UserDetail.class, flipper, bean);
            for (UserDetail user : all) {
                for (String id : userOnline.join()) {
                    if (user.getUserid() == Integer.parseInt(id)) {
                        user.setOnlinestatus(UserDetail.ONLINE_STATUS_ONLINE);
                        break;
                    } else {
                        user.setOnlinestatus(UserDetail.ONLINE_STATUS_OFFLINE);
                    }
                }
                list.add(user);
            }
            return new RetResult<>(new Sheet<>(count, list));
        }
    }

    @RestMapping(auth = true, actionid = ACTION_QUERY, comment = "查询用户详情")
    public RetResult<UserDetail> findUserDetail(int userid) {
        UserDetail user = platfSource.find(UserDetail.class, userid);
        int totalfriends = platfSource.getNumberResult(FriendShip.class, FilterFunc.COUNT, 0, "friendid", FilterNode.create("userid", FilterExpress.EQUAL, userid)).intValue();
        int totalgroups = platfSource.getNumberResult(GroupDetail.class, FilterFunc.COUNT, 0, "groupid", FilterNode.create("createuserid", FilterExpress.EQUAL, userid)).intValue();
        int totaljoingroups = platfSource.getNumberResult(UserGroup.class, FilterFunc.COUNT, 0, "usergroupid", FilterNode.create("userid", FilterExpress.EQUAL, userid)).intValue();
        int totalcomplaint = platfSource.getNumberResult(ComplaintRecord.class, FilterFunc.COUNT, 0, "complaintid", FilterNode.create("targetid", FilterExpress.EQUAL, userid).and("complaintmodule", FilterExpress.EQUAL, ComplaintRecord.USERINFO_MODULE)).intValue();
        user.setTotalfriends(totalfriends);
        user.setTotalgroups(totalgroups);
        user.setTotaljoingroups(totaljoingroups);
        user.setTotalcomplaint(totalcomplaint);
        return new RetResult<>(user);
    }

    public boolean existsUserDetail(int userid) {
        return platfSource.exists(UserDetail.class, userid);
    }

    @RestMapping(auth = true, actionid = ACTION_UPDATE, comment = "更新用户状态")
    public RetResult updateStatus(int userid, short status) {
        return ossService.updateUserStatus(userid, status);
    }

    @RestMapping(auth = true, actionid = ACTION_UPDATE, comment = "重置密码")
    public RetResult resetUserPwd(int userid) {
        return ossService.resetUserPwdByAdmin(userid);
    }
    
    @RestMapping(auth = true, actionid = ACTION_UPDATE, comment = "销毁账号")
    public RetResult destroyAccount(int userid) {
        return ossService.destroyAccount(userid);
    }
    
    @RestMapping(auth = true, actionid = ACTION_UPDATE, comment = "强制下线")
    public RetResult updateOnlinestatus(int userid) {
        webSocketNode.forceCloseWebSocket(userid).join();
        return RetResult.success();
    }

    public String findUserName(int userid) {
        UserDetail user = platfSource.find(UserDetail.class, userid);
        if (user == null) {
            return "";
        }
        return user.getUsername();
    }

    public Map<Integer, String> queryUserNames(HashSet<Integer> userids) {
        Map<Integer, UserDetail> map = platfSource.queryMap(UserDetail.class, SelectColumn.includes("userid","username"), FilterNode.create("userid", userids));
        if (map == null) {
            return null;
        }
        Map<Integer, String> rsmap = new HashMap();
        map.forEach((k, v) -> {rsmap.put(k, v.getUsername());});
        return rsmap;
    }

    @RestMapping(auth = true, actionid = ACTION_QUERY, comment = "查询用户好友列表")
    public RetResult<Sheet<FriendShip>> findFriendShip(Flipper flipper, int userid) {
        Sheet<FriendShip> sheet = platfSource.querySheet(FriendShip.class, flipper, FilterNode.create("userid", userid));
        return new RetResult<>(sheet);
    }
    
    @RestMapping(auth = true, actionid = ACTION_UPDATE, comment = "删除好友")
    public RetResult delFriend(int userid, int friendid) {
        UserInfo user = platfSource.find(UserDetail.class, userid);
        return ossService.removeFriend(user,friendid);
    }

    @RestMapping(auth = true, actionid = ACTION_QUERY, comment = "查询好友聊天记录")
    public RetResult<Sheet<MessageRecordHis>> findFriendShipMsg(Flipper flipper, int userid, int friendid) {
        FilterNode msgFilter = FilterNode.create("msgkind", FilterExpress.EQUAL, MessageRecordHis.MSG_KIND_PRIVATE).and("msgtype", FilterExpress.LESSTHANOREQUALTO, BasicContent.OBJ_IMAGE_MESSAGE);
        FilterNode userFilter = FilterNode.create("fromid", FilterExpress.EQUAL, userid).or("targetid", FilterExpress.EQUAL, userid);
        FilterNode friendFilter = FilterNode.create("fromid", FilterExpress.EQUAL, friendid).or("targetid", FilterExpress.EQUAL, friendid);
        FilterNode filter = userFilter.and(friendFilter);
        Sheet<MessageRecordHis> sheet = platfSource.querySheet(MessageRecordHis.class, flipper, msgFilter.and(filter));
        return new RetResult<>(sheet);
    }
    
    @RestMapping(auth = true, actionid = ACTION_UPDATE, comment = "移入/移出黑名单")
    public RetResult updateBlackList(int userid, int friendid, short status) {
        UserInfo user = platfSource.find(UserDetail.class, userid);
        String friendShipId = userid + "-" + friendid;
        FriendShip friendShip = source.find(FriendShip.class, friendShipId);
        friendShip.setRelationship(status);
        return ossService.updateBlackList(user,friendShip);
    }

}
